//这个是整合代码   测试block    pending    表
#include<iostream>
#include<vector>
#include<functional>
#include<unistd.h>
#include<signal.h>
#include<cstdio>
#include<sys/types.h>


void PrintPending(sigset_t &pending)
{
    printf("我是一个进程（%d）,pending: ",getpid());
    // 从高位往低位进行判断并打印
    for(int signo = 31;signo >= 1;signo--)
    {   
        if(sigismember(&pending,signo))
        {
            std::cout<<"1";
        }
        else
        {
            std::cout<<"0";
        }
    }
    std::cout<<std::endl;
}


//对二号信号实行自定义捕捉
void handlerSig(int sig)
{       
    // 测试 是先递达信号 还是 先把pending标志位由0 置为 1
    std::cout<<"################################"<<std::endl;
    std::cout<<"递达 "<<sig<<" 号信号！"<<std::endl;

    sigset_t pending;
    int m = sigpending(&pending);
    PrintPending(pending);     
    // （如果是0000 0010那就是处理结束，2号再置为0）  （如果是 0000 0000  那就是执行自定义捕捉前，2对应的pending就已经被清理了）
    std::cout<<"################################"<<std::endl;
}
// 答案是：当我们准备递达的时候，要首先清空pending信号集中对应的信号位图 由 1 ---> 0


int  main()
{ 
    signal(SIGINT,handlerSig);           //对二号信号实行自定义捕捉

// 第一步： 屏蔽2号信号
    //屏蔽2号信号，屏蔽2号之前要先把位图清空
    sigset_t block,oblock; 
    sigemptyset(&block);       //清空block位图   
    sigemptyset(&oblock);       


//这是屏蔽 2 号信号
    //    把2号信号添加到接口里
       sigaddset(&block,SIGINT);      //但是只有这一行并没有对2号信号屏蔽完成
    //    因为 block 这个类型是在我们栈上开辟，上面一行只是让block的一个比特位置为了1 ，但是并没有设到当前进程的 block 表的


// 这是把所有信号都屏蔽
    // for(int i=1;i<32;i++)
    // {
    //     sigaddset(&block,i);     //把所有信号全部加到block中  但是会发现 -9 无法被捕捉（管理员信号）
    // }

    
    //设置到表中    修改的时候会把老的pending表给他，但是如果未来想恢复（oblock）
    int n = sigprocmask(SIG_SETMASK,&block,&oblock); 
    (void)n;

// 第四步:  循环包裹，重复打印
int cnt = 0;
while(true)
{
// 第二步： 获取pending信号集合
    sigset_t pending;
    int m = sigpending(&pending);

// 第三步： 打印信号集
    PrintPending(pending);
    
    if(cnt == 10)       //屏蔽到十次  就恢复
    {
        //第五步：恢复对二号信号的block情况   就把老的oblock 传回去  新的老的不关心设置为nullptr
        std::cout<<"解除对2号信号的屏蔽！"<<std::endl;    //也就是屏蔽，如果到时间   就会立刻被递达   无法观察到由1变为0的我过程
        sigprocmask(SIG_SETMASK,&oblock,nullptr);
    }
    cnt++;
    sleep(1);
}
    return 0;
}

